#!/usr/sbin/rsct/perl5/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
#"@(#)05   1.23   src/rsct/rmc/cli/bin/lsactdef.perl, rmccli, rsct_rpyxh, rpyxht1f3 3/7/02 15:33:57"
######################################################################
#                                                                    #
# Module: lsactdef                                                   #
#                                                                    #
# Purpose:                                                           #
#   lsactdef - Lists (displays) action definitions of a resource     #
#              or resource class.                                    #
#                                                                    #
# Syntax:                                                            #
#   lsactdef [-h] [-c] [-p Property] [-s i|o] [-e] [-v]              #
#            [-l|-i|-t|-d|-D Delimiter] [-x] [-T] [-V]               #
#            [Resource_class [Action...]]                            #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes this command's usage statement to stdout.   #
#   -c      Class. Displays the resource class action definitions.   #
#           By default the resource action definitions are displayed.#
#   -p Property Displays actions with the specified Property. By     #
#           default, only the definitions for public actions are     #
#           displayed. To display all action definitions regardless  #
#           of the action property, use the -p 0 flag. Refer to      #
#           ct_mc.h for action properties. An or-ing of the          #
#           properties will be accepted to display any action        #
#           definition that has at least one of the specified        #
#           properties.                                              #
#   -s      Displays the structured data definition for the action   #
#           input or action response.                                #
#           i - Display the action input SD definitions. This is     #
#               the default.                                         #
#           o - Display the action response (output) SD definitions. #
#   -e      Expands the descriptions. By default the definitions are #
#           displayed without the textual descriptions because they  #
#           can be lengthy. Specify this flag to see both the        #
#           definitions and descriptions.                            #
#   -v      Display action input valid values. Since only valid      #
#           values for action inputs are displayed, the -si flag     #
#           must be given in conjunction with the -v flag in order   #
#           to view valid values (if present).                       #
#   -l      Long formatted output. One entry per line. This is the   #
#           default display format. If the lsactdef command is       #
#           issued with the -l flag, but without a resource class    #
#           name, the -l flag is ignored when the command returns    #
#           the list of defined resource class names.                #
#   -i      Input format. Generates a template of the Resource Data  #
#           Input File. The output is displayed in long (stanza)     #
#           format. Which after appropriate editing can be used as   #
#           input to the runact command. The attribute's SD element  #
#           data types are displayed as the value in the Attr=value  #
#           pairs. It is suggested that when you use this flag, the  #
#           output of the lsactdef command be directed to a file.    #
#           The -i flag overrieds the -v flag.                       #
#   -t      Tabular formatted output. Each attribute is displayed    #
#           in a separate column one resource per line.              #
#   -d      Delimiter formatted output. The default delimiter is     #
#           a colon (:). Use the -D flag if you wish to change       #
#           the default delimiter.                                   #
#   -D Delimiter Delimiter-formatted output that uses the specified  #
#           delimiter. Use this flag to specify a delimiter other    #
#           than the default colon (:). An example is when the data  #
#           to be displayed contains colons. Use this flag to        #
#           specify a delimiter of one or more characters.           #
#   -x      Exclude header. Suppress header printing.                #
#   -T      Trace. Writes the command's trace messages to standard   #
#           error. For your software-service organization's use only.#
#   -V      Verbose. Writes this command's verbose messages to       #
#           standard out.                                            #
#                                                                    #
# Operands:                                                          #
#   Resource_class  Resource class name. The name of the resource    #
#                   class whose action definitions you wish          #
#                   displayed. If no Resource_class operand is       #
#                   specified, a list of all the resource class      #
#                   names is displayed.                              #
#                                                                    #
#   Action          If a Resource_class operand is specified, zero   #
#                   or more action names may be specified. If no     #
#                   Action operand is specified, the definitions for #
#                   all the actions for the Resource_class are       #
#                   listed. Specific Action names may be entered     #
#                   to control which attributes are displayed and in #
#                   what order. Actions must be separated by spaces. #
#                                                                    #
# Description:                                                       #
#   The lsactdef command lists the action definitions of a resource  #
#   or resource class. Use lsactdef with no operands specified to    #
#   get a list of all resource class names.                          #
#                                                                    #
#   By default, the Resource action definitions are displayed. To    #
#   see the resource class action definitions, specify the -c flag.  #
#                                                                    #
#   By default, when no actions are specified on the command line,   #
#   only actions that are defined as public are displayed. To        #
#   override this default, use the -p flag or specify on the command #
#   line the names of the actions whose definition you wish to       #
#   display.                                                         #
#                                                                    #
#   To see the structured data definition that is required as input  #
#   when this action is invoked, specify the -s i flag. To see the   #
#   structured data definition linked with the output that results   #
#   from invoking this action, specify the -s o flag.                #
#                                                                    #
#   By default, for the actions that contain descriptions, the       #
#   descriptions are not displayed. Specify the -e flag to display   #
#   the descriptions. Because the translation of these descriptions  #
#   may take some time and because some of the descriptions are very #
#   long, the default is not to display these descriptions. If       #
#   descriptions for members of the valid_vals list are available,   #
#   they are displayed with the -e flag as well.                     #
#                                                                    #
#   By default, for action inputs that have defined valid values, the#
#   valid values are not displayed.  Specify the -v and -si flags to #
#   view the valid values of action input structured data elements.  #
#   Because valid values are not returned as part of the base action #
#   definition of the resource or resource class, and extra calls to #
#   RMC must be made to retrieve the valid values, the default is    #
#   not to display them. Valid_vals and valid_vals_label fields are  #
#   blank for pointer data types.                                    #
#                                                                    # 
#                                                                    #
# Exit Values:                                                       #
#   0  MC_CLI_SUCCESS        Command completed successfully.         #
#   1  MC_CLI_RMC_ERROR      Command terminated due to an underlying #
#                            RMC error.                              #
#   2  MC_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  MC_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  MC_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  MC_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            Resource name as the Resource operand.  #
#                                                                    #
# Examples:                                                          #
#   lsactdef                     (lists all resource class names     #
#   lsactdef IBM.Foo             (lists resource actions definitions)#
#   lsactdef -c IBM.Foo          (lists resouce class actions defs)  #
#   lsactdef -s i -t IBM.Foo     (lists resource actions input SD)   #
#   lsactdef -e IBM.Foo          (lists rsrc actions def with desc)  #
#   lsactdef -s o IBM.Foo ExecuteCommand (lists resource action      #
#                                 response SD for ExecuteCommand     #
#                                 action for IBM.Foo                 #
#   lsactdef -i IBM.Foo          (lists template of action inputs    #
#                                 to use as input to runact command  #
#   lsactdef -v -si -IBM.Foo     (lists resource action input SDs    #
#                                 along with valid values, if present#
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the lsactdef man page in /usr/sbin/rsct/man.                     #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /usr/sbin/rsct/msgmaps/mccli.lsactdef.map - message mapping      #
#   /usr/sbin/rsct/msgmaps/mccli.mccli.map - message mapping         #
#                                                                    #
# Outputs:                                                           #
#   stdout - display of the resource action definitions.             #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  MC_cli_utils.pm, MC_cli_display_utils.pm, MC_cli_rc.pm #
#             CT_cli_utils.pm, CT_cli_data_type_utils                #
#   Extensions:  CT::MC, CT::MCerr, CT::CT                           #
#   Perl library routines: Getopt::Std                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000512 SAB 64351: Initial design & write.                        #
#   010311 SAB 63852: Prepared for GA.                               #
#   010806 YSK 75111: Added -v, valid values support.                #
#   020307 JAC 80687: Remove -v and go back to old usage.            #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands, determine which flavor   #
#    of this command we are actually invoking.                       #
#    This command allows a user to see the Action definitions for    #
#    the specified resource class.                                   #
#    They can select to see one of:                                  #
#       * Names of all defined resource classes on this system.      #
#       * The Resource Class Action Definitions                      #
#       * The Resource Class Action Input Definitions                #
#       * The Resource Class Action Response Definitions             #
#       * The Resource Action Definitions                            #
#       * The Resource Action Input Definitions                      #
#       * The Resource Action Response Definitions                   #
#       * Resource Data Input File format for runact command.        #
# B. Initialize a session with RMC.                                  #
# C. Query the definition of the SD or Action using RMC.             #
# D. Display the requested definitions in the appropriate format.    #
# E. Cleanup.                                                        #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/usr/sbin/rsct/pm";
use locale;
use Getopt::Std; 

use CT::CT qw(:ct_data_type_t);

use autouse CT_cli_utils => qw(
    printIMsg
    printEMsg
);
use autouse CT_cli_data_type_utils => qw(
    data_type_to_string
);

use CT::MC qw(
    :mc_action_props_t
    :mc_qdef_opts_t
    :mc_sd_usage_t
    :mc_vv_usage_t
    :mc_action_type_t

    qdef_resource_class_bp
    qdef_sd_bp
    qdef_valid_values_bp
    qdef_actions_bp
    free_response
);

use CT::MCerr;

use MC_cli_rc qw(:return_codes);
use autouse MC_cli_utils => qw(
    init_session 
    term_session
    build_HoAttr
    qdef_resource_class
    required_attr
    error_exit
    printCEMsg
);
use autouse MC_cli_display_utils => qw(
    display_resource_class_names
    display_resource_data
    convert_properties
    convert_variety_list
    convert_sd_valid_values
    convert_sd_valid_values_label
);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$TRUE = 1;
$FALSE = 0;

$Verbose = $FALSE;                      # default - verbose turned off

# By default output is written in long format.
$Opt_Long_Format = $TRUE;               # default - see -l (long form)
$Opt_Table_Format = $FALSE;             # default - see -t (table)
$Opt_Delm_Format = $FALSE;              # default - see -d (delimiter)
$Opt_Delm_Str = ":";                    # default - see -D (colon :) 
$Opt_No_HDR = $FALSE;                   # default - see -x
$Opt_Exp_Desc = $FALSE;                 # default - see -e
$Opt_LS_Class = $FALSE;                 # default - see -c
$Opt_LS_Input_File = $FALSE;            # default - see -i
$Opt_LS_SD = $FALSE;                    # default - see -s 
$Opt_SD_Input = $FALSE;                 # default - see -s i
$Opt_Valid_Vals = $FALSE;               # default - see -v 

$PROGNAME = "lsactdef";                 # Program Name for messages
$MSGCAT = "mccli.cat";                  # msg catalogue for this cmd

$CTDIR = "/usr/sbin/rsct";              # RSCT root directory
$CTBINDIR = "$CTDIR/bin";               # Cluster Bin directory path
$LSMSG = "$CTBINDIR/ctdspmsg";          # display message rtn.
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG
%Cleanup = ();                          # Hash of items to cleanup
                                        # {Session} $session to term

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
@LoSDAttr = ();
%HoSDDefs = ();
@LoActions = ();
%HoActions = ();

#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#

# Parse the command line, exit if there are errors 
my ($rc, $resource, $req_properties, @actions) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

# Initialize a session with RMC
($rc, $session) = init_session();
($rc == 0) || error_exit($rc);
$Cleanup{Session} = $session;

# If no resource names were specified as an operand to this command
# display the list of all resource names.
if (!$resource) {               # No resource operand
    # Nee a Response Class
    $response = CT::MC::qdef_rsrc_class_rsp_t->new;

    # Let this subroutine handle the real call to the extension
    # and dealing with all of the return codes..
    $rc = qdef_resource_class($session, "", $response, $Opt_Exp_Desc);
    ($rc == 0) || error_exit($rc); 
    
    # Display the Resource Class Definitions
    $rc = display_resource_class_names($response, $Opt_No_HDR, 
        $Opt_Long_Format, 0, $Opt_Delm_Format, $Opt_Delm_Str);
    ($rc == 0) || error_exit($rc);
}

# Create an Input file template suitable for input to runact
# Only 1 action name can be specified.
elsif ($Opt_LS_Input_File) {
    # Need a Response Class
    $response = CT::MC::qdef_sd_rsp_t->new;

    $rc = qdef_sd($session, $resource, \@actions, $response);
    ($rc == 0) || error_exit($rc);

    # Format the Resource or Resource Class SD Actions Definition 
    # into a form suitable for display. There may be 0 or more SDs.
    format_sd_defs_for_input($resource, $response, \@actions, 
        \%HoSDDefs);

    # Display the Resource or Resource Class Action SD elements 
    # in a format suitable for input to runact (once real values
    # are substituted into the attr=value pairs).
    $rc = display_sd_for_input(\@actions, \%HoSDDefs);
    ($rc == 0) || error_exit($rc);
}

elsif ($Opt_LS_SD) {
    # Need a Response Class
    $response = CT::MC::qdef_sd_rsp_t->new;

    # Select the actions that have at least one of the requested
    # properties or were in the list of actions specified on the
    # command line (action operands override -p flag).
    $rc = select_actions($session, $resource, $req_properties, 
        \@actions);
    ($rc == 0) || error_exit($rc);

    # If there are any SD action definitions that should be 
    # displayed (there action has appropriate property) 
    # let the subroutine make the call to the extension, and 
    # handle all the assorted potential errors.
    if (scalar(@actions) > 0) {
        $rc = qdef_sd($session, $resource, \@actions, $response);
        ($rc == 0) || error_exit($rc);

        # Get response for valid values if they were requested by user.
        # Call subroutine to handle valid values extension.
        if ($Opt_Valid_Vals && $Opt_SD_Input) {
            my $usage = $Opt_LS_Class ? MC_VV_USAGE_CLASS_ACTION_INPUT
                                      : MC_VV_USAGE_RSRC_ACTION_INPUT;

            $response_vv = CT::MC::qdef_valid_vals_rsp_t->new;
            $rc = qdef_valid_vals($session, $resource, \@actions,
                $response_vv, $usage);
            ($rc == 0) || error_exit($rc);
        }

        # Format the Resource or Resource Class SD Actions Definition 
        # into a form suitable for display. There may be 0 or more SDs.
        format_sd_defs($resource, $response, \@actions,
            \@LoSDAttr, \%HoSDDefs, $response_vv);
    }

    # Display the Resource or Resource Class Actions Defs & Desc
    $rc = display_sd_defs($resource, \@actions, \@LoSDAttr, 
        \%HoSDDefs);
    ($rc == 0) || error_exit($rc);
}

else {
    # Need a Response to call qdef
    $response = CT::MC::qdef_actions_rsp_t->new;

    # Let the subroutine make the call to the extension, and
    # handle all the assorted potential errors.
    # qdef resource actions (not the resouce class)
    $rc = qdef_actions($session, $resource, $Opt_LS_Class, \@actions, 
        $response);
    ($rc == 0) || error_exit($rc);

    # Format the Query Definition Actions for a Resource into
    # a form suitable for display.  
    format_actions($resource, $response, $req_properties, \@actions, 
                   \@LoActions, \%HoActions);

    # Display the Resource Actions Defs & Desc
    @actions = ();
    $rc = display_actions(\@actions, \@LoActions, \%HoActions); 
    ($rc == 0) || error_exit($rc);
}

if ($response->array_count > 0) {
    $rc = CT::MC::free_response($response);
    ($rc == 0) || error_exit($rc);
}

if (defined($response_vv) && ($response_vv->array_count > 0)) {
    $rc = CT::MC::free_response($response_vv);
    ($rc == 0) || exit $rc;
}

# Cleanup 
$rc = term_session($session);
exit $rc;


#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line - Parse the command line for options and operands.  #
#   Set appropriate global variables as outlined below, make sure we #
#   have a valid combination of arguments / options.                 #
#                                                                    #
# Return:                                                            #
#   $rc   0                  Command line parsed fine, no problem.   #
#         SR_CLI_BAD_FLAG    Command line contained a bad flag.      #
#   $resource                Resource Class Name.                    #
#   $properties              Attributes having these properties      #
#                            should be displayed.                    #
#   @actions                 Array of action names.                  #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Current       output   True (-c) print current cluster info #
#   $Opt_Exp_Desc      output   True (-e) print both definition      #
#                               and description (print all).         #
#   $Opt_LS_Class      output   True (-c) display the class resource #
#                               def vs just the resource def.        #
#   $Opt_LS_Input_File output   True (-i) create/list an input file  #
#                               suitable for runact.                 #
#   $Opt_LS_SD         output   True (-s) display the detailed       #
#                               structured data definition for a     #
#                               attr defined as an SD.               #
#   $Opt_SD_Input      output   True (-s i) display the input action #
#                               SDs, -s o dislplay the output action #
#                               SDs (response SDs).                  #
#   $Opt_Valid_Vals    output   True (-v) display valid values.      #
#   $Opt_Long_Format   output   True (-l) print one entry per line   #
#   $Opt_Table_Format  output   True (-t) table format.              #
#   $Opt_Delm_Format   output   True (-d|-D) print delimiter         #
#                               separated output.                    #
#   $Opt_Delm_Str      output   the string to use as the delimiter,  #
#                               default is colon (:).                #
#   $Opt_No_HDR        output   True (-x) print without header       #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my $resource = "";
my @actions = ();
my %opts = (); 

# Process the command line...
#if (!&getopts('hceip:s:dD:ltxvVT',\%opts)) { # Get options; if errors
if (!&getopts('hceip:s:dD:ltxVT',\%opts)) { # Get options; if errors
    &print_usage;                       # display proper usage
    return MC_CLI_BAD_FLAG;             # return bad rc - bad flag 
}

# Always accept the -h help flag regardless of other flags or operands
if (defined $opts{h}) {                 # -h, help request  
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

# If no operands in lsactdef that is OK, it just means display
# a list of all Resource Class Names

# Get the arguments...
if ($#ARGV >= 0) { 
    $resource = shift @ARGV;            # user specified resource
    @actions = @ARGV;                   # array of action names
}

# See which options/flags were used...

if (defined $opts{c}) {                 # -c, rsrc class definitions
    $Opt_LS_Class = $TRUE;
}

if (defined $opts{e}) {                 # -e, display all desc & def
    $Opt_Exp_Desc = $TRUE;
}

# -i overrides -s  (only action input used for runact)
if (defined $opts{i}) {
    $Opt_LS_Input_File = $TRUE;
    $Opt_SD_Input = $TRUE;
}
elsif (defined $opts{s}) {                 # -s, sd definitions  
    $Opt_LS_SD = $TRUE;
    if ($opts{s} eq "i") {              # qdef SD action input
        $Opt_SD_Input = $TRUE;
    }
    elsif ($opts{s} eq "o") {           # qdef SD action response
        $Opt_SD_Input = $FALSE;
    }
    else {
        # -s flag requires i input | o output (response)
        printCEMsg("EMsgMCcliImproperUsageFlag", "-s $opts{s}");   
        &print_usage;
        return(MC_CLI_BAD_FLAG, $resource); 
    }
}

# The -v flag is overriden by -i and req's -si
if (defined $opts{v}
    && !defined $opts{i}
    && $Opt_SD_Input) {
    $Opt_Valid_Vals = $TRUE;
}

if (defined $opts{p}) {                 # -p Property
    $properties = $opts{p};
    # Make sure properties is a number (hex, octal or decimal)
    if ($properties !~ /^(0x|\d+)\d*/) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        return MC_CLI_USER_ERROR;
    }
    # Convert properties specified in hex or octal to decimal
    $properties = oct $properties if $properties =~ /^0/;

    # Just some mininmal range checking - valid property values only
    # range between 0x0001 to 0x0020 but allow for growth here
    # -p 0 means display actions with any property
    if ($properties < hex("0x0000") || $properties > hex("0xFFFF")) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        return MC_CLI_USER_ERROR;
    }
    if ($properties == 0) {
        $properties = hex("0xFFFF");
    }
}
else {
    # Default to display only public actions
    $properties = MC_RSRC_ACTION_PUBLIC;  # Default to Public property
}


# The -l flag overrides -t which overrides -d which overrides -D flag
# When -i flag used always display in long format
if (defined $opts{l} || defined $opts{i}) { # -l long format,
    $Opt_Long_Format = $TRUE;          #    1 entry per line  
}
elsif (defined $opts{t}) {             # -t tabular format
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{d}) {             # -d delimiter format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{D}) {             # -D <delimiter> format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Str = $opts{D};
}

if (defined $opts{x}) {                # -x do not print header
    $Opt_No_HDR = $TRUE;
}

if (defined $opts{T}) {                # -T turn trace on
    $Trace = $TRUE;
}

if (defined $opts{V}) {                # -V verbose 
    $Verbose = $TRUE;
}

return(0, $resource, $properties, @actions); # success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# print_usage - print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsglsactdefUsage");
}   # end usage


#--------------------------------------------------------------------#
# qdef_actions - function to call the CT::MC::qdef_actions_bp        #
#   extension and handle possible errors.                            #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose       #
#                             action definition we want.             #
#   $query_class_actions in   1 - query resource class actions.      #
#                             0 - query resource actions.            #
#   @$r_actions       input   Reference to array of action names.    #
#   $response         in/out  Response data structure, on output     #
#                             this will point to the real resposne.  #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input  TRUE if display def & description.      #
#   $Opt_LS_Class     input  TRUE if display resource class def      #
#                            versus the resource def.                #
#--------------------------------------------------------------------#
sub qdef_actions
{
my ($session, $resource, $query_class_actions, $r_actions, 
    $response) = @_;
my $rc = 0;
 
my $error = CT::MC::errnum_t->new;

my $options = $Opt_Exp_Desc ? MC_QDEF_OPTS_NONE : MC_QDEF_OPTS_NODSCRP;

my $action_count = scalar(@$r_actions);

$Trace && print STDERR "Calling CT::MC::qdef_actions_bp\n";

$rc = CT::MC::qdef_actions_bp($session, $response, $error,
                              $options, $resource, $query_class_actions,
                              $r_actions, $action_count);

$Trace && print STDERR "Return  CT::MC::qdef_actions_bp\n";

$rc = error_check("mc_qdef_actions_bp", $resource, $response, $rc,
    $error);

return $rc;
}   # end qdef_actions


#--------------------------------------------------------------------#
# qdef_sd - function to call the CT::MC::qdef_sd_bp extension and    #
#   handle possible errors.                                          #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose SD    #
#                             definition we want.                    #
#   @$r_actions       input   Reference to array of action names.    #
#   $response         in/out  Response data structure, on output     #
#                             this will point to the real resposne.  #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#   $Opt_LS_Class     input   TRUE if display resource class def     #
#                             versus the resource def.               #
#   $Opt_SD_Input     input   TRUE if display action input SDs.      #
#                             FALSE if display action response SDs.  #
#--------------------------------------------------------------------#
sub qdef_sd
{
my ($session, $resource, $r_actions, $response) = @_;
my $rc = 0;
 
my $error = CT::MC::errnum_t->new;

my $options = $Opt_Exp_Desc ? MC_QDEF_OPTS_NONE : MC_QDEF_OPTS_NODSCRP;

my $sd_usage = MC_SD_USAGE_RSRC_ACTION_INPUT;
if ($Opt_LS_Class) {
    $sd_usage = MC_SD_USAGE_CLASS_ACTION_INPUT;
    if (!$Opt_SD_Input) {
        $sd_usage = MC_SD_USAGE_CLASS_ACTION_RESPONSE;
    }
}
else {
    if (!$Opt_SD_Input) {
        $sd_usage = MC_SD_USAGE_RSRC_ACTION_RESPONSE;
    }
}

my $action_count = scalar(@$r_actions);

$Trace && print STDERR "Calling CT::MC::qdef_sd_bp\n";

$rc = CT::MC::qdef_sd_bp($session, $response, $error,
                         $options, $resource, $sd_usage, 
                         $r_actions, $action_count);

$Trace && print STDERR "Return  CT::MC::qdef_sd_bp\n";

$rc = error_check("mc_qdef_sd_bp", $resource, $response, $rc, $error);

return $rc;
}   # end qdef_sd


#--------------------------------------------------------------------#
# select_actions - Returns a list of action names that have at least #
#   one of the requested properties or was specified as the action   #
#   operand on the command line. Action operands override -p flag.   #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose       #
#                             action definitions we want.            #
#   $req_properties   input   Return actions with at least one of    #
#                             these properties.                      #
#   @$r_actions       in/out  Reference to list of action names.     #
#                             On input actions from command line     #
#                             (if any).                              #
#                             On output filtered list of act names.  #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if display resource class def     #
#                             versus the resource def.               #
#--------------------------------------------------------------------#
sub select_actions {
my ($session, $resource, $req_properties, $r_actions) = @_;

my @req_actions = ();             
my $action_name; 
my $rc = 0; 

# Need a Response to call qdef
my $response = CT::MC::qdef_actions_rsp_t->new;

# Let the subroutine make the call to the extension, and
# handle all the assorted potential errors.
# qdef resource actions (not the resouce class)
# It also verifies that the specified action names are valid 
$rc = qdef_actions($session, $resource, $Opt_LS_Class, \@actions, 
    $response);
($rc == 0) || error_exit($rc);

my $response_cnt = $response->array_count;
my $actions = CT::MC::action_t->new;
my ($r, $a);

# There should only be 1 response since we only asked for 1 class 
# definition on the qdef_actions call. But code for more. 
for ($r = 0; $r < $response_cnt; $r++) {
    my $action_cnt = $response->action_count($r);
    $response->actions($r, $actions);
    for ($a = 0; $a < $action_cnt; $a++) {
        $action_name = $actions->action_name($a);  

        # Filter out the actions that are not required 
        # Actions requested as operands to this command always get
        # displayed ($r_actions), otherwise display any action
        # that has at least one of the requested properties.
        (required_attr($action_name, $actions->properties($a), 
            $r_actions, $req_properties)) || next;

        push @req_actions, $action_name;
    }
}

if (scalar(@$r_actions) == 0) {
    foreach $action_name (@req_actions) {
        push @$r_actions, $action_name;
    }
}

if ($response->array_count > 0) {
    $rc = CT::MC::free_response($response);
    ($rc == 0) || error_exit($rc);
}

return $rc;
}   # end select_actions


#--------------------------------------------------------------------#
# format_actions - formats the qdef actions into a complex hash of   #
#   attribute elements %rHoAttr which can then be easily displayed   #
#   using utility display_resource_data.                             #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   Response data structure.               #
#   $req_properties   input   Filter out actions that do not have    #
#                             at least one of the specified required #
#                             properties. Actions specified on the   #
#                             comman line override this.             #
#   @$r_actions       input   If Empty format all the actions        #
#                             that have at least one of the required #
#                             properties otherwise only format       #
#                             actions in this list.                  #
#   @$rLoActions      in/out  Reference to the list of action names  #
#                             that are also in HoActions.            #
#   %$rHoActions      in/out  Reference to the hash of actions.      #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub format_actions
{
my($resource, $response, $req_properties, $r_actions, 
    $rLoActions, $rHoActions) = @_;

my($r, $j);

# format each of the actions in the response structure so 
# can use more generic printing....
# permissions is commented out right now since RMC wasn't setting
# it.
my %HoRspAttr = ( 
    "action_name"       => 1,
    "display_name"      => 1,
    "description"       => 1,
    "properties"        => 1,
    "confirm_prompt"    => 1,
    "action_id"         => 1,
    "variety_list"      => 1,
    "variety_count"     => 1,
    "timeout"           => 1,
#   "permissions"       => 1,
);  

my %elements = ();
$response_cnt = $response->array_count;
my $actions = CT::MC::action_t->new;
my $a;
my $i = 0;
# Even though I have a foreach loop here there should only be 1 
# response since we only asked for 1 class definition on the
# qdef_resource_class call.
for ($r = 0; $r < $response_cnt; $r++) {
    $action_cnt = $response->action_count($r);
    $response->actions($r, $actions);
    for ($a = 0; $a < $action_cnt; $a++) {
        
        # Filter out the actions that should not be displayed
        # Actions requested as operand to this command always get
        # displayed ($r_actions), otherwise display any action 
        # that has one of the requested properties.
        (required_attr($actions->action_name($a), 
            $actions->properties($a), $r_actions, $req_properties)) ||
            next;

        if ($HoRspAttr{"action_name"}) {
            %elements = ();
            $elements{at_name} = "action_name";
            $elements{at_dtype} = CT_CHAR_PTR;
            $elements{at_value} = $actions->action_name($a);
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                \%elements, $i);
        }

        if ($HoRspAttr{"display_name"}) {
            %elements = ();
            $elements{at_name} = "display_name";
            $elements{at_dtype} = CT_CHAR_PTR; 
            $elements{at_value} = $actions->display_name($a);
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        if ($HoRspAttr{"description"}) {
            %elements = ();
            $elements{at_name} = "description";
            $elements{at_dtype} = CT_CHAR_PTR;
            $elements{at_value} = $actions->description($a);
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
         }

        if ($HoRspAttr{"properties"}) {
            %elements = ();
            $elements{at_name} = "properties";
            ($elements{at_dtype}, $elements{at_value}) =
                convert_properties($actions->properties($a),
                    "action");
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
         }

        if ($HoRspAttr{"confirm_prompt"}) {
            %elements = ();
            $elements{at_name} = "confirm_prompt";
            $elements{at_dtype} = CT_CHAR_PTR;
            $elements{at_value} = $actions->confirm_prompt($a);
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                \%elements, $i);
         }

        if ($HoRspAttr{"action_id"}) {
            %elements = ();
            $elements{at_name} = "action_id";
            $elements{at_dtype} = CT_UINT32;    # Really a CT_UINT16
            $elements{at_value} = $actions->action_id($a);
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        if ($HoRspAttr{"variety_list"}) {
            %elements = ();
            $elements{at_name} = "variety_list";
            ($elements{at_dtype}, $elements{at_value}) = 
                convert_variety_list($actions, $a,
                    $actions->variety_count($a));
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                \%elements, $i);
         }

        if ($HoRspAttr{"variety_count"}) {
            %elements = ();
            $elements{at_name} = "variety_count";
            $elements{at_dtype} = CT_UINT32;
            $elements{at_value} = $actions->variety_count($a);
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        if ($HoRspAttr{"timeout"}) {
            %elements = ();
            $elements{at_name} = "timeout";
            $elements{at_dtype} = CT_UINT32;
            $elements{at_value} = $actions->timeout($a);
            build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
                 \%elements, $i);
        }

        # TODO: add permissions back in when they really get set
        # Permissions have not been set in this release
        # if ($HoRspAttr{"permissions"}) {
        #    %elements = ();
        #    $elements{at_name} = "permissions";
        #    $elements{at_dtype} = CT_UINT32;
        #    $elements{at_value} = $actions->permissions($a);
        #    build_HoAttr($elements{at_name}, $rLoActions, $rHoActions,
        #         \%elements, $i);
        # }
    
        $i = $i + 1;
    }   # end for actions 
    
}   # end for responses

return;
}   # end format_actions


#--------------------------------------------------------------------#
# format_sd_defs_for_input - formats the structured data definitions #
#   actions.  0 or more SDs may have been defined. A complex hash    #
#   is constructed -                                                 #
#      level 1:  Complex hash                                        #
#                key is action name (see mc_sd_rsp_t in ct_mc.h)     #
#                data hash of definition data for an SD.             #
#      level 2:  Complex hash                                        #
#                key is element name (see mc_sd_element_t in ct_mc.h)#
#                data value                                          #
#      x $rHoSDDefs - to really see what is created.                 #
#      x $$rHoSDDefs{$response->program_name($r)} to see level 2.    #
#      The hash for each action (level 2) can be easily displayed    #
#      using the MC_cli_display_utils::display_resource_data.        #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   Response data structure.               #
#   @$r_actions       input   Reference to the list of actions       #
#                             to be displayed, if empty display all  #
#                             actions.                               #
#   %$rHoSDDefs       in/out  Reference to the hash of Action SD     #
#                             element definitions.                   #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub format_sd_defs_for_input
{
my($resource, $response, $r_actions, $rHoSDDefs) = @_;
my @actions = ();

# format each of the actions in the response structure so
# can use more generic printing....
my ($r, $e);
my $response_cnt = $response->array_count;
for ($r = 0; $r < $response_cnt; $r++) {
    # Building up hash of attr=value pairs where the attribute
    # is really an SD element name, value is the element data type
    my @LoAttr = ();
    my %HoAttr = ();
    my $element_cnt = $response->element_count($r); 
    for (my $e = 0; $e < $element_cnt; $e++) {

        # Filter out elements that have already been processed
        my $element_name = $response->element_name($r, $e);
        (exists $HoAttr{$element_name}) && next;
    
        my %elements = ();
        $elements{at_name} = $element_name; 
        my $data_type = $response->element_data_type($r, $e);
        $elements{at_dtype} = CT_CHAR_PTR;
        $elements{at_value} = data_type_to_string($data_type);
        $elements{at_id} = $response->element_index($r, $e);
        build_HoAttr($elements{at_name}, \@LoAttr, \%HoAttr,
            \%elements, 0);

    } # end for each element

    # Put this Actions SD Attribute definition in the hash with the
    # rest of the Action SD attribute definitions.
    push @actions, $response->program_name($r);
    $$rHoSDDefs{$response->program_name($r)} = { %HoAttr };
}   # end for each response

# If the action array isn't set then set it to the actions return 
# by RMC
if (scalar @$r_actions < 1 && scalar @actions > 0) {
    push @$r_actions, @actions;
}

return;
}   # end of format_sd_defs_for_input


#--------------------------------------------------------------------#
# format_sd_defs - formats the structured data definitions for       #
#   actions.  0 or more SDs may have been defined. A complex hash    #
#   is constructed -                                                 #
#      level 1:  Complex hash                                        #
#                key is action name (see mc_sd_rsp_t in ct_mc.h)     #
#                data hash of definition data for an SD.             #
#      level 2:  Complex hash                                        #
#                key is element_name (see mc_sd_element_t in ct_mc.h)#
#                data value                                          #
#      x $rHoSDDefs - to really see what is created.                 #
#      x $$rHoSDDefs{$response->program_name($r)} to see level 2.    #
#      The hash for each action (level 2) can be easily displayed    #
#      using the MC_cli_display_utils::display_resource_data.        #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   Response data structure.               #
#   @$r_actions       input   Reference to the list of actions to be #
#                             displayed, empty display all actions.  #
#   @$rLoSDAttr       in/out  Reference to the list of SD attributes #
#                             (element fields) that are also in      #
#                             HoSDDefs.                              #
#   %$rHoSDDefs       in/out  Reference to the hash of Action SD     #
#                             element definitions.                   #
#   $response_vv      input   Valid values response structure.       #
#                                                                    #
# Global References:                                                 #
#   $Opt_Valid_Vals   input   TRUE if valid values are being         #
#                             displayed.                             #
#--------------------------------------------------------------------#
sub format_sd_defs
{
my($resource, $response, $r_actions, $rLoSDAttr, $rHoSDDefs, 
    $response_vv) = @_;

my @actions = ();
my $r;

# format each of the Action SDs in the response structure so
# can use more generic printing....

# Hash of field names in the qdef_sd_rsp_t (mc_sd_element_t)
my %HoRspAttr = (
    "element_name"          => 1,
    "display_name"          => 1,
    "description"           => 1,
    "element_data_type"     => 1,
    "element_index"         => 1,
    "valid_vals"            => $Opt_Valid_Vals,
    "valid_vals_label"      => $Opt_Valid_Vals
);

my %elements = ();
$response_cnt = $response->array_count;
for ($r = 0; $r < $response_cnt; $r++) {
    my %HoAttr = (); 
    @$rLoSDAttr = ();
    my $element_cnt = $response->element_count($r);  
    for (my $e = 0; $e < $element_cnt; $e++) {
        if ($HoRspAttr{"element_name"}) {
            %elements = ();
            $elements{at_name} = "element_name";
            $elements{at_dtype} = CT_CHAR_PTR;
            $elements{at_value} = $response->element_name($r, $e);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
                \%elements, 0);
        }

        if ($HoRspAttr{"display_name"}) {
            %elements = ();
            $elements{at_name}  = "display_name";
            $elements{at_dtype} = CT_CHAR_PTR;
            $elements{at_value} = $response->display_name($r, $e);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
                \%elements, 0);
        }

        if ($HoRspAttr{"description"}) {
            %elements = ();
            $elements{at_name} = "description";
            $elements{at_dtype} = CT_CHAR_PTR;
            $elements{at_value} = $response->description($r, $e);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr, 
                \%elements, 0);
        }

        if ($HoRspAttr{"element_data_type"}) {
            %elements = ();
            $elements{at_name} = "element_data_type";
            $data_type = $response->element_data_type($r, $e); 
            $elements{at_dtype} = CT_CHAR_PTR;
            $elements{at_value} = data_type_to_string($data_type);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
                \%elements, 0);
        }

        my $element_index = $response->element_index($r, $e); 
        if ($HoRspAttr{"element_index"}) {
            %elements = ();
            $elements{at_name}  = "element_index";
            $elements{at_dtype} = CT_UINT32;
            $elements{at_value} = $element_index;
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr,
                \%elements, 0);
        } 

        if ($HoRspAttr{"valid_vals"}) {
            %elements = ();
            $elements{at_name} = "valid_vals";
            ($elements{at_dtype}, $elements{at_value}) = 
                convert_sd_valid_values($response_vv, $r,
                    $response_vv->count($r), $data_type, 
                    $element_index);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr, 
                \%elements, 0);
        }                                               

        if ($HoRspAttr{"valid_vals_label"}) {
            %elements = ();
            $elements{at_name} = "valid_vals_label";
            ($elements{at_dtype}, $elements{at_value}) = 
                convert_sd_valid_values_label($response_vv, $r,
                    $response_vv->count($r), $element_index, $data_type);
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoAttr, 
                \%elements, 0);
        }
    } # end for each element

    # Put this SD Attribute definition in the hash with the rest of
    # the SD attributes definitions.
    push @actions, $response->program_name($r);
    $$rHoSDDefs{$response->program_name($r)} = { %HoAttr };
}   # end for each response

# If actions specified on command line display in that order
# otherwise display in the order RMC returned them.
if (scalar @$r_actions < 0 && scalar @actions > 1) {
    push @$r_actions, @actions;
}

return;
}   # end of format_sd_defs


#--------------------------------------------------------------------#
# display_actions - displays the action names and values for         #
#   each element stored in %$rHoAttr. Only the actions that          #
#   are listed in the array $r_actions are displayed using the       #
#   appropriate output format (long, delimitter, or tabular).        #
#   If $r_actions is empty all actions in %$rHoAttr are displayed.   #
#                                                                    #
# Parameters:                                                        #
#   @$r_actions       input   Action names from command line.        #
#   @$rLoActions      input   Reference to List of Action Names      #
#   %$rHoActions      input   Reference to Hash of Actions           #
#                                                                    #
# Returns:                                                           #
#   $rc                       Return code (0 = success).             #
#                                                                    #
# Global References:                                                 #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_actions
{
my($r_actions, $rLoActions, $rHoActions) = @_;

my ($header, $row_title);
my $print_format = "long";
my $delim = "";
my $rc = 0;

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
} 

# Display a catalogued message as the header instead of using
# the header printing capability of display_resource_data
$header = "";
if (!$Opt_No_HDR) {
    ($Opt_LS_Class) ? 
        printIMsg("IMsglsactdefLsRsrcClassActDefHdr", $resource) : 
        printIMsg("IMsglsactdefLsRsrcActDefHdr", $resource);
}
$row_title = "action";

# Display the actions in the order that they were requested
# on the command line.  If no action names were specified on
# the command line display them in the order that RMC returned
# them.

if (scalar(@$r_actions) == 0) {
    $r_actions = $rLoActions;
}

# For debugging to reference one element
# $rHoActions->{$attr_name}[$row]{at_value}

$rc = display_resource_data($print_format, $Opt_No_HDR, $r_actions,
        $row_title, $rHoActions, $delim, $header);

return $rc;
}   # end display_actions


#--------------------------------------------------------------------#
# display_sd_for_input - display the Resource or Resource Class      #
#   SD Action Input Element names and values (values are just the    #
#   data type since action elements do not have default values).     #
#   In a format suitable for input to runact after appropriate       #
#   manual editing.                                                  #
#                                                                    #
# Paramaters:                                                        #
#   @$r_actions       input   Reference to List of Action Names      #
#   %$rHoSDDefs       input   Reference to Hash of Actions and their #
#                             SD elements.                           #
#                                                                    #
# Returns:                                                           #
#   $rc                       0 - for success, non-zero - failure.   #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if displaying Class Action input. #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_sd_for_input
{
my($r_actions, $rHoSDDefs) = @_;

my $row_title = "structured_data";  # programmic name from ct.h
my $print_format = "long";          # input format is long format 
my $delim = "";
my $rc = 0;

(!$Opt_No_HDR && $Opt_LS_Class) &&
    print "ResourceClassAction::\n"; 
(!$Opt_No_HDR && !$Opt_LS_Class) &&
    print "ResourceAction::\n";

if (scalar @$r_actions < 1) {
    push @$r_actions, keys %$rHoSDDefs;
}


my @fields = ();                    # display all fields in HoSDDefs
my $i = 0;
foreach $action (@$r_actions) {
    ($i > 0) && print "\n";
    my $col_title = "# action_name = $action";
    # For debugging to reference one element
    # $rHoSDDefs->{$action_name}{$element_name}
    $rc = display_resource_data($print_format, $Opt_No_HDR, \@fields,
        $row_title, $$rHoSDDefs{$action}, $delim, $col_title);
    ($rc == 0) || return($rc);
    $i++;
}

return $rc;
}   # end display_sd_for_input


#--------------------------------------------------------------------#
# display_sd_defs - displays the SD definition for the action input  #
#   or response for the resource or resource class (-c) specified    #
#   on the command line.  Zero or more SDs may have been formatted   #
#   to be displayed.                                                 #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of resource.                      #
#   @$r_actions       input   Reference to an array of action names, #
#                             the ones to be displayed.              #
#   @$rLoSDAttr       input   Reference to List of SD Element field  #
#                             names.                                 #
#   %$rHoSDDefs       input   Reference to Hash of Actions and their #
#                             SD Elements.                           #
# Returns:                                                           #
#   $rc                       Return code (0 = success)              #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if listing resource class SD defs #
#   $Opt_SD_Input     inupt   TRUE  if listing SD action input defs. #
#                             FALSE if listing SD response defs.     #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_sd_defs 
{
my($resource, $r_actions, $rLoSDAttr, $rHoSDDefs) = @_;

my $print_format = "long";
my $delim = "";
my $rc = 0;

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
} 

# Display a header for the data using a catalgued message
if (!$Opt_No_HDR) {
    if ($Opt_LS_Class) {
        ($Opt_SD_Input) ? 
            printIMsg("IMsglsactdefLsRsrcClassActInHdr", $resource) : 
            printIMsg("IMsglsactdefLsRsrcClassActRspHdr", $resource);
    } 
    else {
        ($Opt_SD_Input) ? 
            printIMsg("IMsglsactdefLsRsrcActInHdr", $resource) : 
            printIMsg("IMsglsactdefLsRsrcActRspHdr", $resource);
    }
}
    
# Display the action SD elements in the order that they were requested
# on the command line. If no Action names were specified on the command
# line display them in the order that RMC returned them.
if (scalar @$r_actions < 1) {
    push @$r_actions, keys %$rHoSDDefs;
}

my $row_title = "sd_element";       # use programmic name for NLS
my $i = 0;
foreach $action (@$r_actions) {
    ($i > 0) && print "\n";
    my $col_title = "action_name $action:"; 
    $rc = display_resource_data($print_format, $Opt_No_HDR, $rLoSDAttr,
        $row_title, $$rHoSDDefs{$action}, $delim, $col_title);
    ($rc == 0) || return($rc);    
    $i++;
}

return($rc);
}   # end display_sd_defs


#--------------------------------------------------------------------#
# qdef_valid_vals - function to call the CT::MC::qdef_valid_         #
#   values_bp extension. Based on above code.                        #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose attr  #
#                             definitions we want.                   #
#   @$r_attributes    input   Reference to array of attribute names. #
#   $response         in/out  Response data structure, on output     #
#                             this will point to the real resposne.  #
#   $usage            input   One of mc_vv_usage_t enum types.       #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#                                                                    #
#TODO: While support for retrieving valid values through action      #
#      invokation is documented in the API, as of 8/6/01, it has not #
#      yet been implemented. Once it is implemented in the RMC C API,#
#      support for retrieving valid values using actions should be   #
#      added to this command.                                        #
#--------------------------------------------------------------------#
sub qdef_valid_vals
{
my ($session, $resource, $r_actions, $response, $usage) = @_;
my $rc = 0;

my $options = $Opt_Exp_Desc ? MC_QDEF_OPTS_NONE : MC_QDEF_OPTS_NODSCRP;

my $error = CT::MC::errnum_t->new;

my $act_count = scalar(@$r_actions); 

$Trace && print STDERR "Calling CT::MC::qdef_valid_values_bp\n";

$rc = CT::MC::qdef_valid_values_bp($session, $response, $error,
                                   $options, $resource, $usage, 
                                   $r_actions, $act_count);

$Trace && print STDERR "Return  CT::MC::qdef_valid_values_bp\n";

$rc = error_check("mc_qdef_valid_values_bp", $resource, $response, 
    $rc, $error);

return $rc;
}   # end qdef_valid_vals


#--------------------------------------------------------------------#
# error_check - checks the return code from the RMC function and     #
#   the error response return code.  If an error is detected         #
#   appropriate error messages will be displayed.                    #
#                                                                    #
# Parameters:                                                        #
#   $rmc_function     in      Name of the rmc function that was      #
#                             called and whose error code we are     #
#                             checking.                              #
#   $rmc_class        in      The rmc class name.                    #
#   $response         in      RMC response                           #
#   $rmc_rc           in      The rmc function return code.          #
#   $error            in      The error response.                    #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($rmc_function, $rmc_class, $response, $rmc_rc, $error) = @_;

my $rc = 0;
my $err_rc = $error->errnum();

if ($rmc_rc != 0) {
    printEMsg("EMsglsactdefLsActDefError", $rmc_class);
    my $rmc_rc_hex = sprintf "0x%8.8lx", $rmc_rc;
    printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function, 
        $rmc_rc, $rmc_rc_hex);
    $rc = MC_CLI_RMC_ERROR;
    return $rc;
}

# Check the errnum in each of the RMC responses
for (my $r = 0; $r < $response->array_count; $r++) {
    # get the error that goes with the specific response
    if ($r > 0) {
        $response->error($error, $r);
        $err_rc = $error->errnum();
    }
    if ($err_rc != 0) {
        if ($err_rc == RMC_ECLASSNOTDEFINED) {
            printCEMsg("EMsgMCcliClassNotDef", $rmc_class);
            $rc = MC_CLI_USER_ERROR;
        }
        elsif ($err_rc == RMC_EBADACTIONNAM) {
            print STDERR $error->error_msg;
            $rc = MC_CLI_USER_ERROR;
        }   
        elsif ($err_rc == RMC_EACCESS) {
            print STDERR $error->error_msg;
            $rc = MC_CLI_USER_ERROR;
        }
        else {
            printEMsg("EMsglsactdefLsActDefError", $rmc_class);
            my $err_rc_hex = sprintf "0x%8.8lx", $err_rc;
            printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function, 
                $err_rc, $err_rc_hex);
            print STDERR $error->error_msg; 
            $rc = MC_CLI_RMC_ERROR;
        }
    }   # end if
}   # end for

return $rc;
}   # end error_check
